package org.ala.tiktools.rpc.plugin.interceptor;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.ala.tiktools.logs.LoggerFactory;
import org.ala.tiktools.tools.BeanTools;
import org.ala.tiktools.tools.list.Lists;
import org.slf4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.ClassUtils;


/**
 *
 *	@author ala
 *	@date 2025年4月23日
 */
public abstract class AbstractRpcInterceptorChain implements IRpcInterceptorChain, ApplicationContextAware {
	static Logger log = LoggerFactory.getLogger("rpc", "chain");
	
	
	/**
	 * 	拦截器类路径
	 */
	protected String[] classes = null;
	/**
	 * 	拦截器列表
	 */
	protected List<IRpcInterceptor> interceptors = new ArrayList<>();
	
	
	
	@Override
	public final void setApplicationContext(ApplicationContext context) throws BeansException {
		//	根据classes初始化
		if (classes == null || classes.length == 0) { return; }
		interceptors = new ArrayList<>(classes.length);
		for (String clazz : classes) {
			try {
				IRpcInterceptor i = (IRpcInterceptor) BeanTools.getBeanOrNew(context, ClassUtils.forName(clazz, this.getClass().getClassLoader()));
				interceptors.add(i);
			} catch (ClassNotFoundException | LinkageError e) {
				throw new RuntimeException(e);
			}
		}
		
		//	给 interceptors 按各自的sort排序
		interceptors.sort((i1, i2) -> i1.sort() - i2.sort());
	}
	protected void doAfterPropertiesSet() {}



	/**
	 * 	默认others已经按sort升序
	 */
	@Override
	public void doInterceptor(Method method, Object[] args, Map<String, Object> metadata) throws Exception {
		if (Lists.isEmpty(interceptors)) { return; }
		else {
			for (IRpcInterceptor i : interceptors) {
				i.doIntercept(method, args, metadata);
			}
		}
	}


	@Override
	public void afterInterceptor(Method method, Object[] args, Object res, Map<String, Object> metadata) throws Exception {
		if (Lists.isEmpty(interceptors)) { return; }
		else {
			try {
				for (IRpcInterceptor i : interceptors) {
					i.afterIntercept(method, args, res, metadata);
				}
			} catch (Exception e) {
				log.error("[{} afterInterceptor] 执行后置拦截器出错", this.getClass().getSimpleName(), e);
			}
		}
	}
	/**
	 * 	
	 */
	public void append(IRpcInterceptor i) { interceptors.add(i); }
	
	public String[] getClasses() {
		return classes;
	}
	public void setClasses(String[] classes) {
		this.classes = classes;
	}
	
}
